package cn.cl.lock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryOneTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractZkLock implements Lock {
    private static  final Logger log= LoggerFactory.getLogger(AbstractZkLock.class);
    public static  final String ZKSERVERPATH = "110.40.208.123:2181";
    public static final Integer TIMEOUT = 50000;
    protected static volatile CuratorFramework zkClient=null;
    protected static final String PATH = "/lock";
    protected String WAIT_PATH;
    protected String CURRENTLOCK;

    //双重检测机制
    public static CuratorFramework getZkClient(){
        if (zkClient==null){
            synchronized (AbstractZkLock.class){
                if (zkClient==null){
                    zkClient = CuratorFrameworkFactory.builder()
                            .connectString(ZKSERVERPATH)
                            .connectionTimeoutMs(TIMEOUT)
                            .retryPolicy(new RetryOneTime(1000))
                            .build();

                    zkClient.start();
                    return zkClient;
                }
            }
        }
        return zkClient;
    }
    @Override
    public void getLock() throws Exception {
        if (tryLock()){
            log.info("开始");
            System.out.println(Thread.currentThread().getName()
                    +"->"+CURRENTLOCK+"获得锁成功");
            return;
        }else {
            waitLock();
            System.out.println(Thread.currentThread().getName()
                    +"->"+CURRENTLOCK+"进入等待锁阶段");
            //再次尝试
            getLock();
        }
    }

    abstract void waitLock() throws Exception;

    abstract boolean tryLock() throws Exception;

    @Override
    public void unLock() {
        try {
            zkClient.delete().forPath(CURRENTLOCK);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
